package org.lmind.srd35.core

import java.util.Random
import org.lmind.srd35.core.item._

class Rule(random: Random) {

  def dice(side: Int, times: Int, bonus: Int) =
    side + random.nextInt(side * times - side) - 1 + bonus;

  /** 属性修正值 */
  def abilityModifier(value: Int) = value / 2 - 5

  def sizeModifier(size: BodySize.Value) = 0

  def attackBonus(attacker: Creature, weapon: Weapon) = {
    var bonus = attacker.baseAttackBonus + sizeModifier(attacker.size)
    if (weapon.isMelee) {
      bonus + abilityModifier(attacker.strength);
    } else {
      bonus + abilityModifier(attacker.dexterity);
    }
    bonus
  }

  def armorClass(target: Creature, weapon: Weapon) = {
    var ac = 10 + abilityModifier(target.dexterity) - sizeModifier(target.size)
    if (!weapon.isTouch && target.armor != null) {
      if (target.armor != null) {
        ac += target.armor.armorBonus
      }
      if (target.shield != null) {
        ac += target.shield.shieldBonus
      }
    }
    ac
  }

  def damage(attacker: Creature, weapon: Weapon) = {
    List((DamageType.Physical, dice(weapon.diceSide, weapon.diceTimes, 0)))
  }

  def attackRoll(attacker: Creature, weapon: Weapon, target: Creature) = {
    var ab = attackBonus(attacker, weapon);
    val ac = armorClass(target, weapon);
    val d = dice(20, 1, 0)
    var dmg: List[(DamageType.Value, Int)] = null
    if (ab + d >= ac) {
      dmg = damage(attacker, weapon);
    }
    new Object {
      def attackBonus = ab
      def armorClass = ac
      def damage = dmg
    }
  }

  def initiativeCheck(list: List[Creature]) = {
    var check = List[(Int, Creature)]()
    for (r <- list) {
      check = (abilityModifier(r.dexterity) + dice(20, 1, 0), r) :: check
    }
    check.sort((a, b) => {
      if (a._1 > b._1) true
      else false
    })
    
    check.map(a => a._2)
  }

}